﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net.PeerToPeer;
using System.Runtime.Remoting.Messaging;
using System.ServiceModel.PeerResolvers;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using monitor_2_DBwork;
using Binding = System.Windows.Data.Binding;
using ContextMenu = System.Windows.Controls.ContextMenu;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using MenuItem = System.Windows.Controls.MenuItem;
using MessageBox = System.Windows.MessageBox;

namespace monitor_server_2_WPF
{
    /// <summary>
    /// Логика взаимодействия для ControlTabControl.xaml
    /// </summary>
    public partial class ControlTabControl : Res.IControlForMainWindow
    {
        class LibsGridItem
        {
            public string DevName { get; set; }
            public string LibName { get; set; }

            public LibsGridItem(string dev, string lib)
            {
                DevName = string.IsNullOrEmpty(dev) ? "" : dev;
                LibName = string.IsNullOrEmpty(lib) ? "" : lib;
            }

            public override int GetHashCode()
            {
                return DevName.GetHashCode() ^ LibName.GetHashCode();
            }

            public LibsGridItem()
            {
                DevName = "";
                LibName = "";
            }

            public static List<string[]> GetStringsArrays(ICollection<LibsGridItem> devLibs)
            {
                var toRet = new List<string[]>(devLibs.Count);
                foreach (var item in devLibs)
                {
                    var strs = new string[3];
                    strs[0] = item.DevName;
                    strs[1] = item.LibName;
                    toRet.Add(strs);
                }
                return toRet;
            }

        }

        private ObservableCollection<LibsGridItem> _devices;
        private OptionsStatus _curStatus = OptionsStatus.Modified;
        string ButText { get; set; }
        public string SecString { get; set; }

        public ControlTabControl()
        {
            InitializeComponent();
            InitUi();
            LibsItem.Header = Res.Rm.GetString("Libraries");
            MonitoringItem.Header = Res.Rm.GetString("Monitoring");
        }

        void InitUi()
        {
            DataContext = this;
            //General
            SaveButLabel.Content = Res.Rm.GetString("Save");
            DiscardButLabel.Content = Res.Rm.GetString("Discard");
            SaveButImage.Source = Res.GetBitMapFromPng("filesaveas_16");
            SaveButImage.Stretch = Stretch.None;
            DiscardButImage.Source = Res.GetBitMapFromPng("revert_16");
            DiscardButImage.Stretch = Stretch.None;
            SecString = Res.Rm.GetString("Sec");
        }

        public UIElement GetControl(out MainWindow.HidingDelegate del)
        {
            del = null;
            //Что-нить сделать наверное надо
            return this;
        }

        private void LibsItem_OnLoaded(object sender, RoutedEventArgs e)
        {
            LibsReset();
            SetStatus(OptionsStatus.Saved);
        }

        public void LibsReset()
        {
            //Получаем список устройств
            var list = DBwork.GetLibs();
            _devices = new ObservableCollection<LibsGridItem>();
            LibsGrid.ItemsSource = _devices;
            foreach (var dev in list)
            {
                _devices.Add(new LibsGridItem(dev[0], dev[1]));
            }
            //SetStatus(OptionsStatus.Saved);
        }

        private void MainTab_OnInitialized(object sender, EventArgs e)
        {
            //Init LibsTab
            var dgc1 = new DataGridTextColumn
            {
                Header = Res.Rm.GetString("Device"),
                Binding = new Binding("DevName")
            };
            var dgc2 = new DataGridTextColumn
            {
                Header = Res.Rm.GetString("Library"),
                Binding = new Binding("LibName")
            };
            
            LibsGrid.AutoGenerateColumns = false;
            LibsGrid.Columns.Add(dgc1);
            LibsGrid.Columns.Add(dgc2);
            ButText = Res.Rm.GetString("Check");
            //Context Menu
            var cm = new ContextMenu
            {
                Background = new SolidColorBrush(Color.FromRgb(0x1B, 0x1B, 0x1C)),
                Template = (ControlTemplate) FindResource("MenuControlTemplate1"),
                ItemContainerStyle = (Style) FindResource("MenuItemStyle1")
            };
            var mi = new MenuItem
            {
                Header = Res.Rm.GetString("DelDevs"),
                Foreground = Brushes.White,
            };
            mi.Click += (o, args) => DeleteLibs();
            cm.Items.Add(mi);
            LibsGrid.ContextMenu = cm;

            //Init MonitoringTabs
            InitMonitoringTab();

        }

        private void LibsGrid_OnKeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Delete)
                return;
            DeleteLibs();
        }

        void DeleteLibs()
        {
            var sc = LibsGrid.SelectedCells;
            if (sc.Count < 1)
                return;
            var items = sc.Select(x => x.Item);
            var dItems = items.Distinct();

            var sb = new StringBuilder();
            var enumerable = dItems as object[] ?? dItems.ToArray();
            foreach (var item in enumerable)
            {
                var it = item as LibsGridItem;
                if (it == null)
                    continue;
                sb.Append(it.DevName + "\r\n");
            }
            sb.Remove(sb.Length - 2, 2);

            var dr = MessageBox.Show(Res.Rm.GetString("DevDelQuestion") + ":\r\n" + sb, Res.Rm.GetString("Warning"), MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);

            if (dr == MessageBoxResult.No)
                return;

            foreach (var dItem in enumerable)
            {
                var it = dItem as LibsGridItem;
                if (it == null)
                    continue;
                _devices.Remove(it);
            }
            SetStatus(OptionsStatus.Modified);
        }

        public void LibsSave()
        {
            try
            {
                DBwork.SetDevLibs(LibsGridItem.GetStringsArrays(_devices));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Res.Rm.GetString("Warning"), MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void LibsGrid_OnInitializingNewItem(object sender, InitializingNewItemEventArgs e)
        {
            var it = e.NewItem as LibsGridItem;
            if(it == null)
                return;
            SetStatus(OptionsStatus.Modified);
            it.DevName = "<" + Res.Rm.GetString("DeviceName") + ">";
            it.LibName = "<" + Res.Rm.GetString("LibraryName") + ">";
        }

        enum OptionsStatus
        {
            Saved,
            Modified,
            SavedNeedRestart
        }

        void SetStatus(OptionsStatus status)
        {
            switch (status)
            {
                case OptionsStatus.Saved:
                    if(_curStatus == OptionsStatus.Saved)
                        return;
                    _curStatus = OptionsStatus.Saved;
                    StatusLabel.Foreground = Brushes.GreenYellow;
                    StatusLabel.Content = Res.Rm.GetString("NoUnsavedChanges");
                    break;
                case OptionsStatus.Modified:
                    if (_curStatus == OptionsStatus.Modified)
                        return;
                    _curStatus = OptionsStatus.Modified;
                    StatusLabel.Foreground = Brushes.Orange;
                    StatusLabel.Content = Res.Rm.GetString("Modified");
                    break;
                case OptionsStatus.SavedNeedRestart:
                    if (_curStatus == OptionsStatus.SavedNeedRestart)
                        return;
                    _curStatus = OptionsStatus.Modified;
                    StatusLabel.Foreground = Brushes.Orange;
                    StatusLabel.Content = Res.Rm.GetString("SavedNeedRestart");
                    break;
                default:
                    throw new ArgumentOutOfRangeException("status");
            }
            StatusLabel.Content += ".";
        }

        private void DiscardButton_OnClick(object sender, RoutedEventArgs e)
        {
            FullReset();
        }

        void FullReset()
        {
            LibsReset();
            OptionsReset();
            SetStatus(OptionsStatus.Saved);
        }

        private void SaveButton_OnClick(object sender, RoutedEventArgs e)
        {
            FullSave();
        }

        void FullSave()
        {
            LibsSave();
            if(OptionsSave())
                SetStatus(OptionsStatus.SavedNeedRestart);
            else
                SetStatus(OptionsStatus.Saved);
        }
        
    }
}
